use std::rc::Rc;
use web_sys::Element;
use yew::{function_component, html, use_node_ref, use_reducer, AppHandle, Html, Reducible};
use yew_hooks::use_mount;
use crate::db::pojo::pojo::{ImGroup, ImUser};
use crate::business::component::im_trait::{Id, Render};
use crate::business::component::list_view::{ListProps, ListView};

#[function_component(UserAndGroupListView)]
pub fn user_and_group_list_view() -> Html{
    let div_ref = use_node_ref();
    let user_group_reducer = use_reducer(move || UserGroupReducer::new());

    let div_ref_clone = div_ref.clone();
    use_mount(move || {
        let div = div_ref_clone
            .cast::<Element>()
            .expect("div_ref not attached to div element");

        let list_props = ListProps { max_size: 1000u16, class: "user-group-list".to_string()};
        let list_app_handle = yew::Renderer::<ListView<UserGroupData>>::with_root_and_props(div, list_props).render();

        load_data(list_app_handle);
    });
    
    html! {
        <div class="user-group-list-view" ref={ div_ref }>

        </div>
    }
}

fn load_data(list_app_handle: AppHandle<ListView<UserGroupData>>) {
    
}

struct UserGroupReducer {
    data_list: Vec<UserGroupData>
}

impl Reducible for UserGroupReducer {
    type Action = UserGroupAction;
    fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
        match action {
            UserGroupAction::Loaded(data_list   ) => {
                Rc::new(Self {
                    data_list
                })
            }
        }
    }
}

enum UserGroupAction {
    Loaded(Vec<UserGroupData>),
}


struct UserGroupData {
    user: Option<ImUser>,
    group: Option<ImGroup>,
}

impl Id for UserGroupData {
    type Value = String;

    fn id(&self) -> Self::Value {
        match &self.user {
            None => {
                match &self.group {
                    None => { panic!()}
                    Some(group) => {
                        format!("group-{}", group.id.clone().unwrap())
                    }
                }
            }
            Some(user) => {
                format!("u-{}", user.id.clone().unwrap())
            }
        }
    }
}

impl Render for UserGroupData {
    fn render(&self) -> Html {
        html! {
            
        }
    }
}

impl UserGroupReducer {
    pub fn new() -> Self {
        Self {
            data_list: vec![],
        }
    }
}

impl PartialEq<Self> for UserGroupData {
    fn eq(&self, other: &Self) -> bool {
        if self.user.is_some() && other.user.is_some() {
            let id1 = self.user.clone().unwrap().id.clone().unwrap();
            let id2 = other.user.clone().unwrap().id.clone().unwrap();
            return id1 == id2;
        }

        if self.group.is_some() && other.group.is_some() {
            let id1 = self.group.clone().unwrap().id.clone().unwrap();
            let id2 = other.group.clone().unwrap().id.clone().unwrap();
            return id1 == id2;
        }

        false
    }
}

impl PartialOrd for UserGroupData {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        let first_letter = get_first_letter(&self);

        let first_letter2 = get_first_letter(&other);

        first_letter.partial_cmp(&first_letter2)
    }
}

fn get_first_letter(user_group: &UserGroupData)-> String {
    match &user_group.user {
        None => {
            match &user_group.group {
                None => { panic!("不能为空")}
                Some(group) => {
                    group.first_letter.clone().unwrap_or_else(||"".to_string())
                }
            }
        }
        Some(user) => {
            user.first_letter.clone().unwrap_or_else(|| "".to_string())
        }
    }
}